package com.youzikj.wx.core.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.apache.log4j.Logger;
import org.dom4j.DocumentException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.mysql.fabric.xmlrpc.base.Array;
import com.youzikj.wx.comm.oauth2.SNSUserInfo;
import com.youzikj.wx.core.comm.Utils;
import com.youzikj.wx.core.dao.PubDao;
import com.youzikj.wx.core.dao.RedDao;
import com.youzikj.wx.core.dao.RefundDao;
import com.youzikj.wx.core.dao.SubDao;
import com.youzikj.wx.core.dao.TaskDao;
import com.youzikj.wx.core.dao.UserDao;
import com.youzikj.wx.core.pojo.Pub;
import com.youzikj.wx.core.pojo.Red;
import com.youzikj.wx.core.pojo.Refund;
import com.youzikj.wx.core.pojo.Sub;
import com.youzikj.wx.core.pojo.Task;
import com.youzikj.wx.core.pojo.User;

@Service
@Transactional
public class CoreServiceImpl implements CoreService{
	
	private static Logger log = Logger.getLogger(CoreServiceImpl.class);

	@Autowired
	private TaskDao taskDao;

	@Autowired
	private PubDao pubDao;

	@Autowired
	private SubDao subDao;

	@Autowired
	private UserDao userDao;

	@Autowired
	private RedDao redDao;
	
	@Autowired
	private RefundDao refundDao;

	public void pubTask(Task task) {
		Pub pub = pubDao.get(task.getPub().getOpenid());
		if(null == pub){

			pubDao.add(task.getPub());
		}
		Integer task_amount =task.getAmount() * task.getTotal_num();
		Integer platform_amount = (int) (task_amount * 0.1);
		Integer total_amount = task_amount + platform_amount;
		task.setTask_amount(task_amount);
		task.setPlatform_amount(platform_amount);
		task.setTotal_amount(total_amount);
		taskDao.add(task);
	}

	public void subTask(Integer taskId, String openId, String posterUrl) {
		Sub sub = subDao.get(openId);
		taskDao.addTaskSub(taskId, sub.getId(), posterUrl);

	}

	public void qrCode(String openId, Integer taskId, Integer subId) {
		Task task = taskDao.get(taskId);
		Integer task_state = task.getTask_state();
		//未结束
		if(task_state != 2){
			User user = userDao.get(openId);
			taskDao.addTaskSubUser(taskId, subId, user.getId());
			taskDao.editCurrent_num(taskId);
			if(task.getTotal_num() == (task.getCurrent_num() + 1)){
				List<Integer> idList = new ArrayList<Integer>();
				idList.add(taskId);
				taskDao.finishTask(idList);
			}
		}

	}

	public void finishTask() {
		String nowDate = Utils.getNowDate("yyyy-MM-dd");
		List<Task> list = taskDao.expireTask(nowDate);
		List<Integer> idList = new ArrayList<Integer>();
		for(int i = 0; i <= list.size();i++){
			Task task = list.get(i);
			Integer taskId = task.getId();
			idList.add(taskId);
		}
		taskDao.finishTask(idList);
	}

	/**
	 * 发送红包：查询已结束未发送红包未结算的任务；
	 * 通过任务ID、领取者ID查询推广次数大于10次的领取者；
	 * 通过任务ID、领取者ID查询领取者的红包记录，如果已发送完整红包，则跳过，否则发送红包，发送成功，则保存红包记录；
	 * 如果红包全部发送成功，则将任务的红包状态修改为已发送
	 */
	public void red() {
		List<String> strList = new ArrayList<String>();
		try {
			List<Task> taskList = taskDao.redTask();
			if(null != taskList){
				for(Task task :taskList){
					for(Sub sub : task.getSubList()){
						Integer taskId = task.getId();
						Integer subId = sub.getId();
						Integer amount = task.getAmount();
						String openid = sub.getOpenid();
						Integer count = taskDao.subCount(taskId, subId);
						if(count >= 10){
							strList.add(new StringBuilder()
							.append(taskId).append("_")
							.append(subId).append("_")
							.append(count).append("_")
							.append(amount).append("_")
							.append(openid)
							.toString());
						}
					}
				}
			}
		} catch (Exception e) {
			log.info("查询已结束未发送红包未结算的任务异常"+e);
		}
		if (strList.isEmpty()) {
			return;
		}
		try {
			for (String str : strList) {
				//判断是否给领取者发送过完整红包，如果已发送，则跳过；如果未发送，获取所有拆分红包，计算红包金额；判断是否需要拆分红包；发送
				//count > 20000;20000,count-20000,
				String[] split = str.split("_");
				Integer taskId = Integer.parseInt(split[0]);
				Integer subId = Integer.parseInt(split[1]);
				Integer count = Integer.parseInt(split[2]);
				Integer amount = Integer.parseInt(split[3]);
				String openid = split[4];
				List<Red> redList = redDao.get(taskId, subId);
				//拆分总金额
				Integer total_red = 0;
				if(redList.isEmpty()){
					return;
				}
				for(Red red : redList){
					if(red.getType() != 2){
						total_red = total_red + red.getAmount();
					}
				}
				//应发金额
				Integer fact_red = count *  amount;
				Integer price = fact_red - total_red;
				if(price > 1000 && price <20000){
					String resultxml = Utils.sendHb(openid, price);
					TreeMap<String,String> map = Utils.Dom2Map(resultxml);
					if(null != map.get("result_code") && "SUCCESS".equals(map.get("result_code"))){
						Red red = new Red();
						red.setAmount(price);
						Sub sub = new Sub();
						sub.setId(subId);
						red.setSub(sub);
						Task task = new Task();
						task.setId(taskId);
						red.setTask(task);
						red.setType(2);
						redDao.add(red);
					}
				}else if(price >20000 && price < 20100){
					String resultxml = Utils.sendHb(openid, 20000);
					TreeMap<String,String> map = Utils.Dom2Map(resultxml);
					if(null != map.get("result_code") && "SUCCESS".equals(map.get("result_code"))){
					Red red = new Red();
					red.setAmount(price);
					Sub sub = new Sub();
					sub.setId(subId);
					red.setSub(sub);
					Task task = new Task();
					task.setId(taskId);
					red.setTask(task);
					red.setType(2);
					redDao.add(red);
				}
			}else if(price > 20100){
					String resultxml = Utils.sendHb(openid, 20000);
					TreeMap<String,String> map = Utils.Dom2Map(resultxml);
					if(null != map.get("result_code") && "SUCCESS".equals(map.get("result_code"))){
						Red red = new Red();
						red.setAmount(price);
						Sub sub = new Sub();
						sub.setId(subId);
						red.setSub(sub);
						Task task = new Task();
						task.setId(taskId);
						red.setTask(task);
						red.setType(1);
						redDao.add(red);
					}
				}
			}
		} catch (Exception e) {
			log.info("发送红包异常"+e);
		}
	}
	
	/**
	 * 修改任务红包状态
	 * 如果红包全部发送成功，则将任务的红包状态修改为已发送
	 */
	public void rebState(){
		List<Task> taskList = taskDao.redTask();
		if(taskList.isEmpty()){
			return;
		}
		List<Integer> idList = new ArrayList<Integer>();
		
		for(Task task : taskList){
			Integer taskId = task.getId();
			FLAG:
			for(Sub sub : task.getSubList()){
				Integer subId = sub.getId();
				List<Red> redList = redDao.get(taskId, subId);
			    if(redList.isEmpty()){
			    	return;
			    }
			    for(Red red : redList){
			    	if(red.getAmount() == null && red.getType() != 2){
			    		break FLAG;
			    	}
			    }
			}
			idList.add(taskId);
		}
		if(idList.isEmpty()){
			try {
				taskDao.finishRedState(idList);
			} catch (Exception e) {
				log.info("修改任务红包状态异常"+e);
			}
		}
	}

	/**
	 * 退款：查询已结束已发送红包未退款的任务；
	 * 通过任务ID查询已发放红包金额、通过任务ID查询已退款金额，计算出退款金额；
	 * 退款；
	 * 如果退款成功，则保存退款记录，并修改退款状态为已退款
	 */
	public void refund() {
		try {
			List<Task> taskList = taskDao.refundTask();
			if(taskList.isEmpty()){
				return;
			 }
				for(Task task : taskList){
					//查询发放金额
					List<Red> redList = redDao.getByTaskId(task.getId());
					Integer reb_total_amount = 0;
					for(Red red : redList){
						Integer amount = red.getAmount();
						reb_total_amount = reb_total_amount+amount;
					}
					//查询退款金额
					List<Refund> refundList = refundDao.getByTaskId(task.getId());
					//已退金额
					Integer ref_total_amount = 0;
					for(Refund refund : refundList){
						Integer amount = refund.getAmount();
						ref_total_amount = ref_total_amount +amount;
					}
					//算出要退款金额
					Integer ref_amount = task.getTask_amount() - reb_total_amount;
					
					Integer price = ref_amount - ref_total_amount;
					//如果退款金额大于0  and  未退款金额大于0
					if(ref_amount > 0 && price >0 && price<=20000){
						//发红包
						 String resultXml = Utils.sendHb(task.getPub().getOpenid(), price);
						 TreeMap<String, String> map = null;
						 try {
							 map = Utils.Dom2Map(resultXml);
						} catch (DocumentException e) {
							e.printStackTrace();
						}
						if(null != map.get("result_code") && "SUCCESS".equals(map.get("result_code"))){
								Refund refund = new Refund();
								refund.setAmount(price);
								refund.setTask(task);
								refund.setPub(task.getPub());
								refund.setType(2);
								refundDao.add(refund);
						}
					}else if(ref_amount > 0 && price >0 && price>20000 && price<20100){
						//退款
						 String resultXml = Utils.sendHb(task.getPub().getOpenid(), 20000);
						 TreeMap<String, String> map = null;
						 try {
							 map = Utils.Dom2Map(resultXml);
						} catch (DocumentException e) {
							e.printStackTrace();
						}
						if(null != map.get("result_code") && "SUCCESS".equals(map.get("result_code"))){
								Refund refund = new Refund();
								refund.setAmount(20000);
								refund.setTask(task);
								refund.setPub(task.getPub());
								refund.setType(2);
								refundDao.add(refund);
						}
					} else if(ref_amount > 0 && price >0 && price >= 20100){
						//退款
						 String resultXml = Utils.sendHb(task.getPub().getOpenid(), 20000);
						 TreeMap<String, String> map = null;
						 try {
							 map = Utils.Dom2Map(resultXml);
						} catch (DocumentException e) {
							e.printStackTrace();
						}
						if(null != map.get("result_code") && "SUCCESS".equals(map.get("result_code"))){
								Refund refund = new Refund();
								refund.setAmount(20000);
								refund.setTask(task);
								refund.setPub(task.getPub());
								refund.setType(1);
								refundDao.add(refund);
						}
					}
				}
		} catch (Exception e) {
			log.info("退款异常"+e);
		}
	}
	
	/**
	 * 修改任务退款状态
	 * 如果退款全部发送成功，则将任务的退款状态修改为已发送
	 */
	public void refundState(){
		List<Task> taskList = taskDao.refundTask();
		if(taskList.isEmpty()){
			return;
		}
		List<Integer> idList = new ArrayList<Integer>();
		for(Task task : taskList){
			//FLAG;
			boolean falg = true;
			Integer taskId = task.getId();
			 Pub pub = task.getPub();
			 List<Refund> refundList = refundDao.get(taskId, pub.getId());
			 if(refundList.isEmpty()){
				 return;
			 }
			 for(Refund refund : refundList){
				 if(refund.getAmount() == null && refund.getType() != 2){
			    		//break FLAG;
					 falg = false;
			    	}
			 }
			 if(falg == false){
				 break;
			 }
			idList.add(taskId);
		}
		if(idList.isEmpty()){
			try {
				taskDao.finishRefundState(idList);
			} catch (Exception e) {
				log.info("修改任务退款状态异常"+e);
			}
		}
	}

	public List<Task> all(){
		return taskDao.all();
	}

	public Task getBySubId(Integer taskId, Integer subId){
		return taskDao.getBySubId(taskId, subId);
	}

	public Task get(Integer taskId){
		return taskDao.get(taskId);	
	}


}
